package com.shoplook2025.category.api.ServiceImpl;

import com.shoplook2025.category.api.dao.CategoryMapper;
import com.shoplook2025.category.model.Category;
import com.shoplook2025.category.service.CategoryService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yan
 * @date 2025/8/26
 */
@CacheConfig(cacheNames = "category-api")
@Service
public class CategoryServiceImpl implements CategoryService {

    private CategoryMapper categoryMapper;
    @Autowired
    public void setCategoryMapper(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Override
    public List<Category> findAll(Category category) {
        return categoryMapper.findAll(category);
    }

    @Cacheable(key = "'all'")
    @Override
    public List<Category> findAll() {
        return categoryMapper.selectList(null);
    }

    @Cacheable(key = "'tree'")
    @Override
    public List<Category> findTree() {
        //使用代理调用，可以触发aop
        List<Category> categories =proxy().findAll();
        return makeTree(categories);
    }

    @Cacheable(key = "#id")
    @Override
    public Category findById(Integer id) {
        List<Category> roots = proxy().findTree();
        return findById(roots,id);
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean save(Category category) {
        return categoryMapper.insert(category) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean update(Category category) {
        return categoryMapper.updateById(category) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int deleteById(Integer id) {
        Category cat = proxy().findById(id);
        if(cat.getChildren()!=null){
            throw new UnsupportedOperationException("请先删除子分类");
        }
        return this.categoryMapper.deleteById(id);
    }

    //生成树形结构
    private List<Category> makeTree(List<Category> categories){
        Map<Integer,Category> cache = new HashMap<>();
        for(Category category:categories){
            cache.put(category.getId(),category);
        }

        List<Category> roots = new ArrayList<>();
        //遍历所有分类
        for(Category category:cache.values()){
            if (category.getParentId()==null){
                roots.add(category);
            }else {
                Category parent = cache.get(category.getParentId());
                if (parent == null){
                    throw new RuntimeException("父级分类不存在");
                }
                //设置关联
                category.setParent(parent);
                if(parent.getChildren()==null){
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(category);
            }
        }

        return roots;
    }

    //在一个分类集合中找指定集合的父级分类
    private Category findById(List<Category> categories,Integer id){
        for(Category category:categories){
            if (category.getId().equals(id)){
                return category;
            }
            if(category.getChildren()!=null){
                Category found = findById(category.getChildren(),id);
                if(found!=null){
                    return found;
                }
            }
        }
        return null;
    }

    //获取代理对象
    private CategoryService proxy(){
        return (CategoryService) AopContext.currentProxy();
    }
}
